/**************************************************
 * Project Name         [JavaEE_XML]
 * File Name            [Dom4jAPI.java]
 * Creation Date        [08-20-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 **************************************************/
package pkg_03_dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.DOMReader;
import org.dom4j.io.HTMLWriter;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class Dom4jAPI {

	/**
	 * 从文件解析XML
	 * 
	 * @param file
	 * @return
	 * @throws DocumentException
	 */
	public Document parseXMLWithSAX(File file) throws DocumentException {
		SAXReader xmlReader = new SAXReader();
		Document document = xmlReader.read(file);
		return document;
	}

	/**
	 * 从URL解析XML
	 * 
	 * @param url
	 * @return
	 * @throws DocumentException
	 */
	public Document parseXMLWithSAX(URL url) throws DocumentException {
		SAXReader xmlReader = new SAXReader();
		Document document = xmlReader.read(url);
		return document;
	}

	/**
	 * W3C Document 转换为Dom4j Document
	 * 
	 * @param w3cDocument
	 * @return
	 */
	public Document convertW3CDOM(org.w3c.dom.Document w3cDocument) {
		DOMReader xmlReader = new DOMReader();
		return xmlReader.read(w3cDocument);
	}

	/**
	 * 创建Document
	 * 
	 * @return
	 */
	public Document createDocument() {
		Document document = DocumentFactory.getInstance().createDocument();
		Element rootElement = document.addElement("students");

		Element studentElement = rootElement.addElement("学生");
		studentElement.addAttribute("student_id", "00003");

		Element nameElement = studentElement.addElement("name");
		nameElement.addText("杨舸");

		Element ageElement = studentElement.addElement("age");
		ageElement.addText("30");

		Element genderElement = studentElement.addElement("gender");
		genderElement.addText("男");

		Element birthdayElement = studentElement.addElement("birthday");
		birthdayElement.addText("1984-03-24");

		return document;
	}

	/**
	 * 输出XML文档(不要使用字节流, 会产生编码问题)
	 * 
	 * @param out
	 * @param encoding
	 * @throws IOException
	 */
	public void serializedToXML(OutputStream out, String encoding)
			throws IOException {
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding(encoding);
		XMLWriter writer = new XMLWriter(out, format);
		writer.write(createDocument());
		writer.flush();
		// 2014-09-08 Add closure code
		writer.close();
	}

	/**
	 * 输出HTML文档(不要使用字节流, 会产生编码问题)
	 * 
	 * @param out
	 * @param encoding
	 * @throws IOException
	 */
	public void serializedToHTML(OutputStream out, String encoding)
			throws IOException {
		OutputFormat format = OutputFormat.createCompactFormat();
		format.setEncoding(encoding);
		HTMLWriter writer = new HTMLWriter(out, format);
		writer.write(createDocument());
		writer.flush();
		// 2014-09-08 Add closure code
		writer.close();
	}

	/**
	 * 遍历DOM
	 * 
	 * @throws DocumentException
	 */
	public void interateDocument() throws DocumentException {
		Document document = this.parseXMLWithSAX(new File(
				"src/xml/Student_Dom4j.xml"));
		Element root = document.getRootElement();
		Iterator<Element> domIterator = root.elementIterator();
		while (domIterator.hasNext()) {
			Element childElement = domIterator.next();
			System.out.println(childElement.getName() + "--->"
					+ childElement.getText());
		}
	}

	/**
	 * 基于导航的快速索引
	 * 
	 * @throws DocumentException
	 */
	public void treeWalk() throws DocumentException {
		Document document = this.parseXMLWithSAX(new File(
				"src/xml/Student_Dom4j.xml"));
		treeWalk(document.getRootElement());
	}

	public void treeWalk(Element element) {
		for (int i = 0, size = element.nodeCount(); i < size; i++) {
			Node node = element.node(i);
			if (node instanceof Element) {
				treeWalk((Element) node);
			} else {
				System.out.println(node.getText());
			}
		}
	}

	/**
	 * 增加Element
	 * 
	 * @param newElement
	 * @param parentElement
	 * @param index
	 */
	public void insertElement(Element newElement, Element parentElement,
			int index) {
		List<Node> parentList = parentElement.content();
		parentList.add(index, newElement);
	}

	/**
	 * 修改Element
	 * 
	 * @param element
	 */
	public void changeElement(Element element) {
		element.setName("newName");
		element.setText("newText");
	}

	/**
	 * 测试方法
	 * 
	 * @param args
	 * @throws IOException
	 * @throws DocumentException
	 */
	public static void main(String[] args) throws IOException,
			DocumentException {
		FileOutputStream out = new FileOutputStream(new File(
				"src/xml/Student_Dom4j.xml"));
		new Dom4jAPI().serializedToXML(out, "UTF-8");

		out = new FileOutputStream(new File("src/xml/Student_Dom4j.html"));
		new Dom4jAPI().serializedToHTML(out, "UTF-8");

		new Dom4jAPI().interateDocument();
		new Dom4jAPI().treeWalk();
	}
}
